package biz;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import util.PageVO;

import com.mysql.jdbc.StringUtils;

import dao.RoleDao;
import dao.SysLogDao;
import dao.UserDao;
import dao.UserInfoDao;
import entity.Menu;
import entity.MenuComparator;
import entity.Role;
import entity.Syslog;
import entity.User;

@Service
@Transactional
public class SystemBiz {
	@Autowired
	private UserDao userDao;
	@Autowired
	private UserInfoDao userInfoDao;
	@Autowired
	private RoleDao roleDao;
	@Autowired
	private SysLogDao sysLogDao;
	
	public User findUser(String name, String password) {
		return userDao.findUser(name, password);
	}
	public User findUser(String userName, int userId) {
		if (userId>0) {
			return userDao.findUser(userName, userId);
		} else {
			return userDao.findUser(userName);
		}
	}
	
	public User getUserById(int id){
		return userDao.getById(id);
	}
	
	public PageVO<User> listUsersByPage(User user,Role userRole,int pageIndex,int pageSize){
		DetachedCriteria dc=DetachedCriteria.forClass(User.class);
		dc.createAlias("userinfo", "info");
		if(userRole.getId()==1){
			if (user.getRole().getId()>0) {
				dc.add(Restrictions.eq("role.id", user.getRole().getId()));
			}else{
				dc.add(Restrictions.in("role.id", new Integer[]{2,3}));
			}
		}else if(userRole.getId()==2){
			dc.add(Restrictions.eq("role.id", 3));
		}else{
			if (user.getRole().getId()>0) {
				dc.add(Restrictions.eq("role.id", user.getRole().getId()));
			}else{
				dc.add(Restrictions.in("role.id", new Integer[]{1,2,3}));
			}
		}
		
		if(!StringUtils.isNullOrEmpty(user.getUname())){
			dc.add(Restrictions.like("uname", user.getUname(), MatchMode.ANYWHERE));
		}
		
		if (user.getUserinfo()!=null &&!StringUtils.isNullOrEmpty(user.getUserinfo().getSex())) {
			dc.add(Restrictions.eq("info.sex", user.getUserinfo().getSex()));
		}
		if (user.getUserinfo()!=null &&!StringUtils.isNullOrEmpty(user.getUserinfo().getName())) {
			dc.add(Restrictions.like("info.name", user.getUserinfo().getName(), MatchMode.ANYWHERE));
		}
		if(user.getStatus()!=-1){
			dc.add(Restrictions.eq("status", user.getStatus()));
		}
		return userDao.listByPage(dc,pageIndex,pageSize);
	}
	
	public List<Role> listRoles(int roleId){
		return roleDao.find("from Role where id>?", roleId);
	}
	
	public List<Menu> getMenus(User user) {
		user=userDao.getById(user.getId());
		// 得到顶级菜单列表
		List<Menu> menus = new ArrayList<Menu>();
		for (Object m : user.getRole().getMenus()) {
			Menu menu=(Menu) m;
			if (menu.getLevel()==0) {
				menus.add(menu);
			}
		}
		// 填充子菜单
		for (Menu menu : menus) {
			menu = fillSubMenu(menu, user.getRole());
		}
		Collections.sort(menus, new MenuComparator());
		return menus;
	}
	private Menu fillSubMenu(Menu menu, Role role) {
//		获取指定角色，指定父菜单的所有子菜单
		List<Menu> subMenus = new ArrayList<Menu>();
		for (Object obj : role.getMenus()) {
			Menu m=(Menu) obj;
			int pid=m.getPid()==null?0:m.getPid();
			int id=menu.getId();
			if (pid==id) {
				subMenus.add(m);
			}
		}
		Collections.sort(subMenus, new MenuComparator());
		//递归填充子菜单
		if (subMenus != null && subMenus.size() > 0) {
			menu.setSubMenus(new ArrayList<Menu>());
		}
		for (Menu sm : subMenus) {
			Menu m = this.fillSubMenu(sm, role);
			if (m.getSubMenus() != null && m.getSubMenus().size() > 0) {
				menu.getSubMenus().add(0, m);
			} else {
				menu.getSubMenus().add(m);
			}
		}
		return menu;
	}
	
	public boolean updateUser(User user) {
		return userDao.update(user);
	}
	
	public int addUser(User user) {
		Integer userId=(Integer) userDao.add(user);
		return userId>0?userId:0;
	}
	public boolean delUser(int userId) {
		return userDao.delete(userDao.getById(userId));
	}
	public boolean updateUserStatus(int[] ids, int status) {
		boolean res=true;
		for (int id : ids) {
			User user = userDao.getById(id);
			user.setStatus(status);
			if (!userDao.update(user)) {
				res=false;
			}
		}
		return res;
	}
	public int addLog(Syslog syslog){
		return (int) sysLogDao.add(syslog);
	}

}
